#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <list>
#include <stack>
#include <unistd.h>
#include <climits>

using namespace std;

//1.mutex与lock_guard
// std::mutex _mtx;
// std::list<int> _list;
// void add_to_list(int value) //mutex不方便
// {
//     _mtx.lock();
//     _list.push_back(value);
//     _mtx.unlock();
// }
// bool list_contains(int value_to_find) //lock_guard自动解锁
// {
//     std::lock_guard<std::mutex> guard(_mtx);
//     auto it = _list.begin();
//     while(it!=_list.end())
//     {
//         if(*it==value_to_find) return true;
//         it++;
//     }
//     return false;
// }

//2.无意传递一个指针或者引用导致的数据安全问题
// class some_data
// {
// private:
//     int a;
//     std::string b;
// public:
//     void do_something();
// };
// class data_wrapper
// {
// private:
//     some_data _data;
//     std::mutex _mtx;
// public:
//     template<class Funciton>
//     void process_data(Funciton func)
//     {
//         std::lock_guard<std::mutex> guard(_mtx);
//         func(_data);
//     }
// };
// some_data* mydata;
// void func(some_data& data)
// {
//     mydata=&data;
// }
// data_wrapper x;
// void foo()
// {
//     x.process_data(func); //危险,里面的东西即使上锁也能被拿取
//     mydata->do_something(); //拿取的指针就不再拥有任何安全保障了
// }

//3.stack设计
////3.1有问题的设计.内部没问题但是外部访问有问题
// template<class T>
// class thread_stack_notsafe
// {
// private:
//     std::stack<T> _data;
//     mutable std::mutex _mtx;
// public:
//     thread_stack_notsafe(){}
//     thread_stack_notsafe(const thread_stack_notsafe& ts)
//     {
//         std::lock_guard<std::mutex> guard(_mtx);
//         _data=ts->_data;
//     }
//     thread_stack_notsafe& operator=(const thread_stack_notsafe& ts) = telete;
//     void push(T value)
//     {
//         std::lock_guard<std::mutex> guard(_mtx);
//         data.push(std::move(value));
//     }
//     T pop()
//     {
//         std::lock_guard<std::mutex> guard(_mtx);
//         auto element = data.top();
//         data.pop();
//         return element;
//     }
//     bool empty() const
//     {
//         std::lock_guard<std::mutex> guard(_mtx);
//         return data.empty();
//     }
// };
// void test_threadsafe_stack1() {
//     thread_stack_notsafe<int> notsafe_stack;
//     notsafe_stack.push(1);
//     std::thread t1([&notsafe_stack]() {
//         if (!notsafe_stack.empty()) {
//             std::this_thread::sleep_for(std::chrono::seconds(1));
//             notsafe_stack.pop();
//             }
//         });
//     std::thread t2([&notsafe_stack]() {
//         if (!notsafe_stack.empty()) {
//             std::this_thread::sleep_for(std::chrono::seconds(1));
//             notsafe_stack.pop();
//         }
//     });
//     t1.join();
//     t2.join();
// }
////3.2抛出异常 - 外层还要去接到异常处理
// struct empty_stack : std::exception
// {
//     const char* what() const throw();
// };
// template<class T>
// class safe_thread
// {
//     std::shared_ptr<T> pop()
// 	{
// 		std::lock_guard<std::mutex> lock(m);
// 		if (data.empty()) throw empty_stack();
// 			std::shared_ptr<T> const res(std::make_shared<T>(data.top()));    
// 			data.pop();
// 		return res; //防止拷贝内容过大
// 	}
//     T pop()
//     {
//         std::lock_guard<std::mutex> lock(m);
//         if (data.empty()) throw empty_stack();
//         auto element = data.top();
//         data.pop();
//         return element;
//     }
// };

//4.死锁问题
// //4.1产生死锁
// std::mutex t_lock1;
// std::mutex t_lock2;
// int m_1 = 0;
// int m_2 = 1;
// void dead_lock1() {
//     while (true) {
//         std::cout << "dead_lock1 begin " << std::endl;
//         std::lock_guard<std::mutex> guard1(t_lock1);
//         sleep(1);
//         m_1 = 1024;
//         std::lock_guard<std::mutex> guard2(t_lock2);
//         m_2 = 2048;
//         std::cout << "dead_lock1 end " << std::endl;
//     }
// }
// void dead_lock2() {
//     while (true) {
//         std::cout << "dead_lock2 begin " << std::endl;
//         std::lock_guard<std::mutex> guard2(t_lock2);
//         sleep(1);
//         m_2 = 2048;
//         std::lock_guard<std::mutex> guard1(t_lock1);
//         m_1 = 1024;
//         std::this_thread::sleep_for(std::chrono::milliseconds(5));
//         std::cout << "dead_lock2 end " << std::endl;
//     }
// }
// void test_dead_lock() {
//     std::thread t1(dead_lock1);
//     std::thread t2(dead_lock2);
//     t1.join(); //gdb走到这里就能确认是死锁了
//     t2.join();
// }
// //4.2同时加锁
// std::mutex t_lock1;
// std::mutex t_lock2;
// int m_1 = 0;
// int m_2 = 1;
// void dead_lock1() {
//     while (true) {
//         std::cout << "dead_lock1 begin " << std::endl;
//         std::scoped_lock<std::mutex,std::mutex> scoped_lock(t_lock1,t_lock2);
//         sleep(1);
//         m_1 = 1024;
//         m_2 = 2048;
//         std::cout << "dead_lock1 end " << std::endl;
//     }
// }
// void dead_lock2() {
//     while (true) {
//         std::cout << "dead_lock2 begin " << std::endl;
//         std::scoped_lock<std::mutex,std::mutex> scoped_lock(t_lock2,t_lock1);
//         sleep(1);
//         m_2 = 2048;
//         m_1 = 1024;
//         std::cout << "dead_lock2 end " << std::endl;
//     }
// }
// //4.3将每一个操作原子化,一个锁干一件事情分离出来 - 但是不是通解需要具体题目具体分析,故懒得写出来了

//5.层级锁 -- 用于检测是否会出现死锁问题
// class hierarchical_mutex
// {
// private:
//     std::mutex _mtx;
//     //当前传递层级锁
//     const unsigned long _hierarchy_value;
//     //本线程未更新的上一次层级值
//     unsigned long _previous_hierarchy_value;
//     //本线程未更新时记录的层级值
//     static thread_local  unsigned long  _this_thread_hierarchy_value;
//     //更新 - 感觉类似于链表尾插
//     void update_hierarchy_value()
//     {
//         _previous_hierarchy_value=_this_thread_hierarchy_value;
//         _this_thread_hierarchy_value=_hierarchy_value;
//     }
//     void check_for_hierarchy_value()
//     {
//         if(_this_thread_hierarchy_value<=_hierarchy_value)
//             throw std::logic_error("mutex hierarchy value error");
//     }
// public:
//     explicit hierarchical_mutex(unsigned long value)
//     :_hierarchy_value(value)
//     {}
//     //单例,一次生成一个对象
//     hierarchical_mutex(const hierarchical_mutex&) = delete;
//     hierarchical_mutex& operator=(const hierarchical_mutex&) = delete;
//     void lock()
//     {
//         check_for_hierarchy_value();
//         _mtx.lock();
//         update_hierarchy_value();
//     }
//     void unlock()
//     {
//         _this_thread_hierarchy_value = _previous_hierarchy_value;
//         _mtx.unlock();
//     }
//     bool try_lock()
//     {
//         check_for_hierarchy_value();
//         if (!_mtx.try_lock()) {
//             return false;
//         }
//         update_hierarchy_value();
//         return true;
//     }
// };
// thread_local unsigned long hierarchical_mutex::_this_thread_hierarchy_value(ULONG_MAX);
//
// void test_hierarchy_lock()
// {
//     hierarchical_mutex hmtx1(16810);
//     hierarchical_mutex hmtx2(6414);
//     std::thread t1([&hmtx1, &hmtx2]() {
//         hmtx1.lock();
//         hmtx2.lock();
//         hmtx2.unlock();
//         hmtx1.unlock();
//         });
//     std::thread t2([&hmtx1, &hmtx2]() {
//         hmtx2.lock();
//         hmtx1.lock();
//         hmtx1.unlock();
//         hmtx2.unlock();
//         });
//     t1.join();
//     t2.join();
// }

int main()
{
    //1.mutex与lock_guard
    // vector<thread> vt;
    // for(int i=0;i<5;++i)
    //     vt.emplace_back(std::thread(add_to_list,i));
    // for(auto& e:vt) e.join();

    //4.死锁
    // test_dead_lock();
    // try
    // {
    //     test_hierarchy_lock();
    // }
    // catch(std::logic_error e)
    // {
    //     cerr<<"Exception: "<<e.what()<<endl;
    // }
    
    return 0;
}